//
//  GSMapManager.m
//  GasStation
//
//  Created by vedon on 2/1/16.
//  Copyright © 2016 vedon. All rights reserved.
//

#define kMapAppKey @"I01IZbij2VWZYTz4xBWisYjhWddG8vB5"
#define kMaximumRetryLocationTimes 3

#import "GSMapManager.h"
#import "GSMapMacro.h"
#import <BaiduMapAPI_Location/BMKLocationComponent.h>
#import "ObserverContainer.h"
#import "UIAlertView+BlocksKit.h"

@interface GSMapManager ()<BMKGeneralDelegate,BMKMapViewDelegate,BMKLocationServiceDelegate,CLLocationManagerDelegate>
@property (nonatomic,strong) BMKMapManager *mapManager;
@property (nonatomic,strong) BMKLocationService *locService;
@property (nonatomic,strong) ObserverContainer *observers;
@property (nonatomic,strong) CLLocationManager *locationManager;
@property (nonatomic,assign) NSUInteger retryTimes;
@property (nonatomic,assign) BOOL isShowPromptEnableLocationService;
@end

@implementation GSMapManager

+ (instancetype)shareManager
{
    
    //单例 ： 程序中唯一存在的一个对象，不会被销毁，除非程序被　kill　掉。百度单例
    static GSMapManager *_shareInstance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _shareInstance = [[GSMapManager alloc] init];
    });
    
    return _shareInstance;
}

- (instancetype)init
{
    self = [super init];
    if (self)
    {
        self.mapManager = [[BMKMapManager alloc]init]; //地图主引擎
        self.locService = [[BMKLocationService alloc] init]; //定位服务
        self.locationManager = [[CLLocationManager alloc] init];
        self.locationManager.delegate = self;
        self.locService.delegate = self;
        self.retryTimes = 0;
    }
    return self;
}

#pragma mark - Public

- (void)initialize
{
    BOOL ret = [_mapManager start:kMapAppKey generalDelegate:self];
    if (!ret) {
        assert(0);
    }
}


//添加观察者到数组里面
- (void)addObserver:(id<GSMapManagerProtocol>)observer
{
    assert(observer);
    if (observer)
    {
        [self.observers addObserver:observer];
    }
}


//移除观察者
- (void)removeObserver:(id<GSMapManagerProtocol>)observer
{
    assert(observer);
    if (observer)
    {
        [self.observers removeObserver:observer];
    }
}

- (void)startLocateMyLocation
{
    //询问系统，是否允许app 访问用户的地理位置。可以去到设置那里把定位功能关闭测试一下
    if (![self isEnableLocateUserLocation])
    {
        
        //[self.locationManager requestAlwaysAuthorization];
        if (!self.isShowPromptEnableLocationService) {
            self.isShowPromptEnableLocationService = YES;
            NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary];
            NSString *app_Name = [infoDictionary objectForKey:@"CFBundleDisplayName"];
            NSString *prompt = [NSString stringWithFormat:@"请在\"设置-隐私-定位服务\"选项中，\r允许%@访问你的位置",app_Name];
            [UIAlertView bk_showAlertViewWithTitle:prompt message:@"" cancelButtonTitle:@"确定" otherButtonTitles:nil handler:^(UIAlertView *alertView, NSInteger buttonIndex) {
                
                self.isShowPromptEnableLocationService = NO;
                
            }];
        }
        return;
    }
    
    [self.locService startUserLocationService];

}

- (void)stopLocateMyLocation
{
    [self.locService stopUserLocationService];
}

- (BMKUserLocation *)userLocation
{
    return self.locService.userLocation;
}

#pragma mark - Private

- (BOOL)isEnableLocateUserLocation
{
    BOOL isEnable = YES;
    switch ([CLLocationManager authorizationStatus]) {
        case kCLAuthorizationStatusNotDetermined:
        case kCLAuthorizationStatusAuthorizedAlways:
        case kCLAuthorizationStatusAuthorizedWhenInUse:
            isEnable = YES;
            break;
        case kCLAuthorizationStatusDenied:
        case kCLAuthorizationStatusRestricted:
            isEnable = NO;
            break;
        default:
            break;
    }
    
    return isEnable;
}

#pragma mark -  CLLocationManagerDelegate

- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
{
    switch ([CLLocationManager authorizationStatus]) {
        case kCLAuthorizationStatusNotDetermined:
        case kCLAuthorizationStatusAuthorizedAlways:
        case kCLAuthorizationStatusAuthorizedWhenInUse:
        {
            [self startLocateMyLocation];
        }
            
            break;
        case kCLAuthorizationStatusDenied:
        case kCLAuthorizationStatusRestricted:
            
            break;
        default:
            break;
    }

}

#pragma mark - BMKLocationServiceDelegate

- (void)willStartLocatingUser
{
    GSLog(@"开始定位");
}

- (void)didStopLocatingUser
{
    GSLog(@"停止定位");
}

- (void)didUpdateUserHeading:(BMKUserLocation *)userLocation
{
   //当观察者个数不为零时
    if (self.observers.observerCount)
    {
        
        //询问观察者是否实现了协议中的方法，如果是则把事件和数据交给代理（delegate）处理。
        
        [self.observers enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            
            //一定要问观察者是否实现协议，如果实现了就触发该事件。如果观察者没有实现方法，却调用该方法，程序会崩溃！
            if ([obj respondsToSelector:@selector(didGetUserCurrentLocation:)])
            {
                [obj didGetUserCurrentLocation:userLocation];
            }
        }];
    }
   
}

- (void)didUpdateBMKUserLocation:(BMKUserLocation *)userLocation
{
    GSLog(@"成功定位");
    GSLog(@"didUpdateUserLocation lat %f,long %f",userLocation.location.coordinate.latitude,userLocation.location.coordinate.longitude);
    if (self.observers.observerCount)
    {
        [self.observers enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            if ([obj respondsToSelector:@selector(didGetUserCurrentLocation:)])
            {
                [obj didGetUserCurrentLocation:userLocation];
            }
        }];
    }
    
    [self stopLocateMyLocation];

}

- (void)didFailToLocateUserWithError:(NSError *)error
{
    GSLog(@"定位失败");
    self.retryTimes ++;
    
    
    //尝试定位三次，三次定位失败就不再尝试。由用户主动定位
    if (self.retryTimes > kMaximumRetryLocationTimes)
    {
        self.retryTimes = 0;
        if (self.observers.observerCount)
        {
            [self.observers enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                
                
                if ([obj respondsToSelector:@selector(didFailToGetUserLocation)])
                {
                    [obj didFailToGetUserLocation];
                }
            }];
        }
        
        //如果成功拿到用户位置，停止定位
        [self stopLocateMyLocation];
    }
    else
    {
        //2 秒之后执行定位方法。
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            
            //获取用户当前位置
            [self startLocateMyLocation];
        });
    }
}


#pragma mark - Getter && Setter

- (ObserverContainer *)observers
{
    if (!_observers)
    {
        _observers = [[ObserverContainer alloc] init];
    }
    return _observers;
}
@end
